package com.ruoyi.web.controller.front;

import com.alibaba.fastjson2.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.config.AlipayConfig;
import com.ruoyi.utils.FileUploadUtils;
import com.ruoyi.utils.JwtUtils;
import com.ruoyi.utils.MyThreadLocal;
import com.ruoyi.vpn.domain.VpnOrder;
import com.ruoyi.vpn.domain.VpnPlan;
import com.ruoyi.vpn.domain.VpnUser;
import com.ruoyi.vpn.service.IVpnCarmiService;
import com.ruoyi.vpn.service.IVpnOrderService;
import com.ruoyi.vpn.service.IVpnPlanService;
import com.ruoyi.vpn.service.IVpnUserService;
import com.ruoyi.vpn.service.impl.VpnOrderServiceImpl;
import org.junit.jupiter.api.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Date;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import static com.alipay.api.AlipayConstants.CHARSET;
import static com.alipay.api.AlipayConstants.SIGN_TYPE;

@Anonymous
@RestController
@RequestMapping("alipay")
public class AlipayController {
    @Autowired
    private JwtUtils jwtUtils;
    @Autowired
    private IVpnUserService vpnUserService;
    @Autowired
    private IVpnCarmiService VpnCarmiService;
    @Resource(name = "myFileUpLoadUtils")
    private FileUploadUtils fileUploadUtils;
    @Autowired
    private IVpnOrderService vpnOrderService;
    @Autowired
    private IVpnPlanService vpnPlanService;

    @Autowired
    private AlipayConfig alipayConfig;

    @GetMapping("pay")
    @Transactional
    public AjaxResult pay(Integer planId, Integer userId, HttpServletResponse httpServletResponse) throws Exception {
        //通过套餐id查询套餐详情
        VpnPlan vpnPlan = vpnPlanService.selectVpnPlanByPlanId(Long.valueOf(planId));
        //生成订单号
        LocalDateTime now = LocalDateTime.now();
        int year = now.getYear();
        int month = now.getMonthValue();
        int day = now.getDayOfMonth();
        int hour = now.getHour();
        int minute = now.getMinute();
        int second = now.getSecond();
        StringBuilder stringBuilder = new StringBuilder();
        String orderId = stringBuilder.append(year).append("-").append(month).append("-").append(day).append("-").append(hour).append("-").append(minute).append("-").append(second).append("-").append(userId).toString();
        //创建订单信息
        VpnOrder vpnOrder = new VpnOrder();
        vpnOrder.setOrderId(orderId);
        vpnOrder.setUserId(userId.longValue());
        vpnOrder.setPlanId(vpnPlan.getPlanId());
        vpnOrder.setStatus(0L);
        //插入订单
        vpnOrderService.insertVpnOrder(vpnOrder);
        System.out.println("config = " + alipayConfig);
        // 获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", alipayConfig.getAppId(), alipayConfig.getAppPrivateKey(), "json", "UTF-8", alipayConfig.getAlipayPublicKey(), "RSA2");
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        // 定义变量
        String outTradeNo = orderId; // 商户订单号
        String totalAmount = String.valueOf(vpnPlan.getPrice()); // 订单总金额
        String subject = vpnPlan.getName(); // 订单标题
        String storeId = "myStore1"; // 商店ID
        String timeoutExpress = "90m"; // 订单允许的最晚付款时间
        // 拼接bizContent字符串
        String bizContent = "{" +
                "\"out_trade_no\":\"" + outTradeNo + "\"," + // 商户订单号
                "\"total_amount\":\"" + totalAmount + "\"," +
                "\"subject\":\"" + subject + "\"," +
                "\"store_id\":\"" + storeId + "\"," +
                "\"product_code\":\"" + "FACE_TO_FACE_PAYMENT" + "\"," +
                "\"timeout_express\":\"" + timeoutExpress + "\"}"; // 订单允许的最晚付款时间
        request.setBizContent(bizContent);
        request.setNotifyUrl(alipayConfig.getNotifyUrl());
        String body = alipayClient.execute(request).getBody();
        //阿里请求结果封装对象
        JSONObject jsonObject = JSONObject.parseObject(body);
        return AjaxResult.success(jsonObject);
    }
    @PostMapping("notify")
    public String notify(HttpServletRequest request) throws Exception {
        Map<String, String> params = new HashMap<String, String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
//公钥验签示例代码
        boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayConfig.getAlipayPublicKey(), "utf-8", "RSA2");

//公钥证书验签示例代码
//   boolean flag = AlipaySignature.rsaCertCheckV1(params,alipayPublicCertPath,"UTF-8","RSA2");

        if (signVerified) {
            System.out.println("验签成功111");
            // TODO 验签成功后
            //按照支付结果异步通知中的描述，对支付结果中的业务内容进行1\2\3\4二次校验，校验成功后在response中返回success
            if (params.get("trade_status").equals("TRADE_SUCCESS")) {

                System.out.println("成功支付");
                VpnOrder vpnOrder = new VpnOrder();
                vpnOrder.setStatus(1L);
                String orderId = params.get("out_trade_no");
                vpnOrder.setOrderId(orderId);
                vpnOrderService.updateVpnOrder(vpnOrder);


                //给用户充值流量
                //通过订单id查询用户
                VpnOrder selectOrder = vpnOrderService.selectVpnOrderByOrderId(orderId);
                System.out.println("selectOrder = " + selectOrder);
                VpnUser vpnUser = selectOrder.getVpnUser();
                System.out.println("vpnUser = " + vpnUser);
                VpnPlan vpnPlan = vpnPlanService.selectVpnPlanByPlanId(selectOrder.getVpnPlan().getPlanId());
                Long days = vpnPlan.getDays();

                Long bandwidth = vpnPlan.getBandwidth();

                System.out.println("bandwidth = " + bandwidth);
                //设置流量
                vpnUser.setBandwidth(bandwidth*1024);
                //设置时间
                vpnUser.setExpirationTime(Date.from(LocalDateTime.now().plusDays(days).atZone(ZoneId.systemDefault()).toInstant()));

               vpnUserService.updateVpnUser(vpnUser);


                return "success";
            }
        } else {
            // TODO 验签失败则记录异常日志，并在response中返回fail.
            System.err.println("验签失败============================");
        }
        return "fail";
    }

    @GetMapping("verifyIsPay")
    public AjaxResult verifyIsPay(String orderId){
        VpnOrder vpnOrder = vpnOrderService.selectVpnOrderByOrderId(orderId);

        if (vpnOrder.getStatus() ==1){
            return  AjaxResult.success("已支付",vpnOrder);
        }

        return AjaxResult.error("未支付");



    }




}
